﻿
Imports System.Threading

Public Class rcclient4
    Inherits _rcclient(Of eventComb, tcpTalk4, fixpoint_talk4pool_t)

    Public Sub New(ByVal host As String, ByVal port As Int32,
                    Optional ByVal holdtimeMs As Int64 = tcpTalk4.defaultHoldTimeMs,
                    Optional ByVal livetimeMs As Int64 = tcpTalk4.defaultLiveTimeMs)
        MyBase.New(host, port, holdtimeMs, livetimeMs)
    End Sub

    Protected Overrides Function async_talk(ByRef ec As eventComb,
                                            ByVal talk As tcpTalk4,
                                            ByVal returnTypes() As Type,
                                            ByVal rtns As pointer(Of fromBytes())) As Boolean
        Dim talkec As eventComb = Nothing
        ec = New eventComb(Function() As Boolean
                               Return talk.talk(talkec) AndAlso waitfor(talkec) AndAlso [goto](1)
                           End Function,
                           Function() As Boolean
                               Return talk_finish(talkec.end_result(), talk, returnTypes, rtns) AndAlso
                                      goto_end()
                           End Function)
        Return True
    End Function

    Protected Overrides Function generateTalkPool(ByVal host As String,
                                                  ByVal port As Int32,
                                                  ByVal holdtimeMs As Int64,
                                                  ByVal livetimeMs As Int64) As fixpoint_talk4pool_t
        Return New fixpoint_talk4pool_t(host, port, holdtimeMs, livetimeMs)
    End Function

    Private Const datasizeUpperBound As Int32 = 128
    Private Shared bts() As bytesbytes
#If NETWORK Then
    Private Shared Function createData(ByVal i As Int64) As toBytes
        Dim index As Int64 = 0
        index = i Mod datasizeUpperBound
        If index < 0 Then
            index += datasizeUpperBound
        End If
        If bts(index) Is Nothing Then
            Dim b As bytes = Nothing
            b = New bytes()
            b.size() = ((index + 1) << 10)
            atomic.eva(bts(index), New bytesbytes(b))
        End If

        Return bts(index)
    End Function
#Else
    Private Shared Function createData(ByVal i As Int64) As toBytes
        Return New bytesInt64(i)
    End Function
#End If

    Private Shared Function isnetwork() As Boolean
#If NETWORK Then
        return true
#Else
        Return False
#End If
    End Function

    Public Shared Sub unittest()
        Dim host As String = Nothing
        host = Environment.GetEnvironmentVariable("host")
        If isemptystring(host) Then
            host = network.localhost
        End If
        ReDim bts(datasizeUpperBound - 1)
        Const testsize As Int64 = 9999999999999999

        Console.WriteLine(longTime())
        Dim threadcount As Int64 = 0
        threadcount = (Environment.ProcessorCount() << 1)
        Dim client As rcclient4 = Nothing
        client = New rcclient4(host, share.unittest.port)
        Dim ecs() As eventComb = Nothing
        ReDim ecs(threadcount - 1)
        For j As Int64 = 0 To threadcount - 1
            Dim rtns As pointer(Of fromBytes()) = Nothing
            rtns = New pointer(Of fromBytes())()
            Dim i As Int64 = -testsize
            Dim invokeec As eventComb = Nothing
            Dim k As Int64 = 0
            k = j
            ecs(j) = New eventComb(Function() As Boolean
                                       Return client.invoke(share.unittest.unittestInvokeName,
                                                            invokeec, rtns, createData(i)) AndAlso
                                              waitfor(invokeec) AndAlso
                                              [goto](1)
                                   End Function,
                                   Function() As Boolean
                                       If (isdebugmode() OrElse Not isnetwork()) AndAlso
                                          invokeec.end_result() AndAlso
                                          compare(rcserve4.unittestInvoke(
                                                                createData(i)).tobytes(),
                                                                convertor.cast(Of toBytes)(rtns.get()(0)).tobytes()) _
                                                 <> 0 Then
                                           raiseError(errorHandle.errorType.exclamation,
                                                      "error found when i = ", i)
                                       End If
                                       If _inc(i) < testsize Then
                                           If k = 0 AndAlso (i Mod 1000) = 0 Then
                                               Console.Write(
                                                   Convert.ToString(i * threadcount) + character.tab + character.return)
                                           End If
                                           Return [goto](0)
                                       Else
                                           If k = 0 Then
                                               Console.WriteLine()
                                           End If
                                           Return goto_end()
                                       End If
                                   End Function)
            assert_begin(ecs(j))
        Next
        For j As Int64 = 0 To threadcount - 1
            While Not ecs(j).end()
                sleep(10)
            End While
        Next
        Console.WriteLine(longTime())
    End Sub
End Class
